package com.zzyl.nursing.service.impl;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson2.JSON;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.core.domain.AjaxResult;
import com.zzyl.common.core.domain.R;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.framework.config.properties.AliIoTConfigProperties;
import com.zzyl.nursing.dto.DeviceDto;
import com.zzyl.nursing.vo.DeviceVo;
import com.zzyl.nursing.vo.ProductVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.service.IDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import javax.xml.transform.Result;
import java.util.Arrays;
import java.util.Map;

/**
 * 设备Service业务层处理
 *
 * @author ruoyi
 * @date 2024-12-13
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService {
    @Autowired
    private DeviceMapper deviceMapper;


    /**
     * 查询设备列表
     *
     * @param device 设备
     * @return 设备
     */
    @Override
    public List<Device> selectDeviceList(Device device) {
        return deviceMapper.selectDeviceList(device);
    }


    @Autowired
    private Client client;

    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 同步产品列表
     *
     * @return
     */
    @Override
    public AjaxResult syncProductList() {
        //1.调用阿里云iot平台系统,获取产品列表
        QueryProductListRequest request = new QueryProductListRequest();
        request.setCurrentPage(1);
        request.setPageSize(100);
        //设置公共实例
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        //创建连接阿里云的配置
        QueryProductListResponse response = null;
        try {
            response = client.queryProductList(request);
        } catch (Exception e) {
            throw new BaseException("查询产品列表异常");
        }
        if (!response.getBody().getSuccess()) {
            throw new BaseException("查询产品列表失败");
        }
        String jsonString = JSON.toJSONString(response.getBody().getData().getList().getProductInfo());
        //将数据同步到redis中
        redisTemplate.opsForValue().set(CacheConstants.IOT_PRODUCT_LIST_ALL, jsonString);
        return AjaxResult.success();
    }

    /**
     * 查询所有产品(从redis中查询)
     *
     * @return
     */
    @Override
    public List<ProductVo> allProduct() {
        //1.从Redis中获取数据
        String productJsonStr = (String) redisTemplate.opsForValue().get(CacheConstants.IOT_PRODUCT_LIST_ALL);
        //2.将数据封装到集合中
        List<ProductVo> productVos = JSON.parseArray(productJsonStr, ProductVo.class);
        return productVos;
    }

    /**
     * 新增设备
     *
     * @param dto
     * @return
     */
    @Override
    public AjaxResult register(DeviceDto dto) {
        Device device = new Device();
        BeanUtils.copyProperties(dto, device);
        //1.首先判断设备名称是否重复,重复不允许添加
        long count = count(Wrappers.<Device>lambdaQuery().eq(Device::getDeviceName, dto.getDeviceName()));
        if (count > 0) {
            throw new BaseException("设备名不允许重复");
        }
        //2.调用iot接口新增设备(返回设备唯一标识)
        String iotId = addDevice(dto);
        //3.调用iot接口查询设备对应的产品名称(表中有这个字段)
        String productName = queryProduct(dto);
        //4.根据localType判断设备的类型(0随身 1固定)  设置设备物理位置(老人-1)
        if (dto.getLocationType() == 0) {
            //是随身
            device.setPhysicalLocationType(-1);
        }

        //setPhysicalLocationType(dto, device);
        //5.封装新增数据插入到数据库中
        device.setIotId(iotId);
        device.setProductName(productName);
        boolean flag = save(device);
        //6.判断新增设备是否成功,不成功删除iot平台的设备,保证设备的一致性
        deleteDevice(flag, iotId);
        //7.返回结果
        return AjaxResult.success();
    }

    @Override
    public R<DeviceVo> queryDeviceDetail(DeviceDto dto) {
        //1.根据doiId查询数据库获取基本信息
        Device device = getOne(Wrappers.<Device>lambdaQuery().eq(Device::getIotId, dto.getIotId()));
        //2.调用iot平台接口查询设备详情
        QueryDeviceDetailRequest request = new QueryDeviceDetailRequest();
        request.setIotId(dto.getIotId());

        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDeviceDetailResponse response;
        try {
            response = client.queryDeviceDetail(request);
        } catch (Exception e) {
            throw new BaseException("请求iot平台查询设备详情异常");
        }
        DeviceVo deviceVo = JSON.parseObject(JSON.toJSONString(response.getBody().getData()), DeviceVo.class);
        BeanUtils.copyProperties(device, deviceVo);
        return R.ok(deviceVo);
    }

    /**
     * 查看指定产品的已发布物模型中的功能定义详情
     *
     * @param dto
     * @return
     */
    @Override
    public AjaxResult queryThingModelPublished(DeviceDto dto) {
        QueryThingModelPublishedRequest request = new QueryThingModelPublishedRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setProductKey(dto.getProductKey());
        QueryThingModelPublishedResponse response;
        try {
            response = client.queryThingModelPublished(request);
        } catch (Exception e) {
            throw new BaseException("请求iot平台查看产品已发布物模型异常");
        }
        return AjaxResult.success(response.getBody().getData());
    }

    /**
     * 查询指定设备的物模型运行状态
     *
     * @param dto
     * @return
     */
    @Override
    public AjaxResult queryDevicePropertyStatus(DeviceDto dto) {
        QueryDevicePropertyStatusRequest request = new QueryDevicePropertyStatusRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setProductKey(dto.getProductKey());
        request.setDeviceName(dto.getDeviceName());
        QueryDevicePropertyStatusResponse response;
        try {
            response = client.queryDevicePropertyStatus(request);
        } catch (Exception e) {
            throw new BaseException("请求iot平台查看设备物模型运行状态异常");
        }
        QueryDevicePropertyStatusResponseBody.QueryDevicePropertyStatusResponseBodyData data = response.getBody().getData();
        return AjaxResult.success(data);
    }

    /**
     * 修改设备
     *
     * @param dto
     * @return
     */
    @Override
    public AjaxResult edit(DeviceDto dto) {
        Device device = new Device();
        BeanUtils.copyProperties(dto, device);
        boolean flag = updateById(device);
        if (flag) {
            //调用iot平台修改设备信息
            updateDeviceNickName(dto);
        }
        return AjaxResult.success();
    }

    /**
     * 删除设备
     *
     * @param dto
     * @return
     */
    @Override
    public AjaxResult deleteDevice(DeviceDto dto) {
        boolean flag = remove(Wrappers.<Device>lambdaQuery().eq(Device::getIotId, dto.getIotId()));
        if (flag) {
            //调用iot平台删除设备
            DeleteDeviceRequest request = new DeleteDeviceRequest();
            request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
            request.setIotId(dto.getIotId());
            try {
                client.deleteDevice(request);
            } catch (Exception e) {
                throw new BaseException("删除设备异常");
            }
        }
        return AjaxResult.success();
    }

    private void updateDeviceNickName(DeviceDto dto) {
        BatchUpdateDeviceNicknameRequest request = new BatchUpdateDeviceNicknameRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo list =
                new BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo();
        list.setIotId(dto.getIotId());
        list.setNickname(dto.getNickname());
        List<BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo> list1 = new ArrayList<>();
        list1.add(list);
        request.setDeviceNicknameInfo(list1);
        try {
            client.batchUpdateDeviceNickname(request);
        } catch (Exception e) {
            throw new BaseException("修改设备备注异常");
        }
    }

    private void deleteDevice(boolean flag, String iotId) {
        if (!flag) {
            //新增失败,调用iot平台,删除设备
            DeleteDeviceRequest request = new DeleteDeviceRequest();
            request.setIotId(iotId);
            try {
                client.deleteDevice(request);
            } catch (Exception e) {
                throw new BaseException("请求iot平台删除设备异常");
            }
        }
    }

    /**
     * 设置setPhysicalLocationType
     *
     * @param dto
     * @param device
     */
    private void setPhysicalLocationType(DeviceDto dto, Device device) {
        if (dto.getLocationType() == 0) {
            //是随身
            device.setPhysicalLocationType(-1);
        } else {
            //是固定位置分为三种
            int number = getNumber(dto); //2就是床位  1就是房间  0就是楼层
            if (number == 0) {
                device.setPhysicalLocationType(0);
            } else if (number == 1) {
                device.setPhysicalLocationType(1);
            } else {
                device.setPhysicalLocationType(2);
            }
        }
    }

    /**
     * 判断设备描述中逗号的个数(物理位置到底是楼还是房间还是床)
     *
     * @param dto
     * @return
     */
    private int getNumber(DeviceDto dto) {
        String str = dto.getDeviceDescription();
        int number = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == ',') {
                number++;
            }
        }
        return number;
    }

    private String queryProduct(DeviceDto dto) {
        QueryProductRequest request = new QueryProductRequest();
        request.setProductKey(dto.getProductKey());
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryProductResponse response = null;
        try {
            response = client.queryProduct(request);
        } catch (Exception e) {
            throw new BaseException("请求iot平台查询产品异常");
        }
        String jsonString = JSON.toJSONString(response.getBody().getData());
        Map map = JSON.parseObject(jsonString, Map.class);
        return (String) map.get("productName");
    }

    private String addDevice(DeviceDto dto) {
        RegisterDeviceRequest request = new RegisterDeviceRequest();
        request.setProductKey(dto.getProductKey());
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setDeviceName(dto.getDeviceName());
        request.setNickname(dto.getNickname());
        RegisterDeviceResponse response = null;
        try {
            response = client.registerDevice(request);
        } catch (Exception e) {
            throw new BaseException("请求iot平台新增设备异常");
        }
        return response.getBody().getData().getIotId();
    }
}
